home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-04-14 | 11.7 KB | 415 lines | [TEXT/KAHL] |
- /******************************************************************************
- CToolPens.c
-
- The ToolPens Class
-
- SUPERCLASS = CPaintTask
-
- Copyright © 1989 Symantec Corporation. All rights reserved.
-
- ******************************************************************************/
-
- #include "Global.h"
- #include "TBUtilities.h"
- #include "CToolPens.h"
-
- extern RgnHandle gUtilRgn; /* Utility region */
-
- extern CBitMap *gScratchPad;
- extern Pattern gPattern; /* The current fill pattern */
- extern short gLineSize;
-
- #define SHIFTKEY_CODE 0x38 /* Hardware code for the shift key */
- #define iPAINTING 7 /* Index for Painting task name */
- #define iERASER 8 /* Index for Erase task name */
- #define iPENCIL 9 /* Index for Pencil task name */
-
- #define ERASER_LENGTH 16 /* Size of eraser in pixels */
- #define BRUSH_LENGTH 4 /* Size of brush in pixels */
-
-
- /**** C O N S T R U C T I O N / D E S T R U C T I O N M E T H O D S ****/
-
-
- /******************************************************************************
- CToolPens
- ******************************************************************************/
-
- CToolPens::CToolPens(short aNameIndex, CPaintPane *aPaintPane,CBitMap *aPainting)
- : CPaintTask(aNameIndex, aPaintPane, aPainting)
- {}
-
-
- /******************************************************************************
- BeginTracking {OVERRIDE}
-
- Mouse down tracking is about to begin at the specified starting
- point. Set the pen size and fill pattern.
- ******************************************************************************/
-
- void CToolPens::BeginTracking(
- LongPt *startPt)
- {
- /* Copy entire image to scratch pad */
- CopyBits(itsPainting->macBitMap, gScratchPad->macBitMap,
- &itsPainting->macBitMap->bounds, &itsPainting->macBitMap->bounds,
- srcCopy, NULL);
-
- PenNormal();
- }
-
-
- /******************************************************************************
- KeepTracking {OVERRIDE}
-
- Continuous mouse tracking while the mouse button is down. Draw
- only when the mouse moves or the panorama autoscrolls.
- ******************************************************************************/
-
- void CToolPens::KeepTracking(
- LongPt *currPt,
- LongPt *prevPt,
- LongPt *startPt)
- {
- LongRect currRect;
-
- if (itsPaintPane->AutoScroll(currPt) || !EqualLongPt(currPt, prevPt)) {
- itsPaintPane->GetFrame(&currRect);
- PinInRect(&currRect, currPt);
- UseTool(currPt, prevPt);
- }
- }
-
-
- /******************************************************************************
- CalcPenRect
-
- Calculate the rectangle affected by a pen tool located at a
- specified point
- ******************************************************************************/
-
- void CToolPens::CalcPenRect(
- LongPt *thePt,
- LongRect *penRect)
- {
- penRect->left = thePt->h; /* Pen hangs below and to the right */
- penRect->top = thePt->v; /* of its coordinate location */
- penRect->right = thePt->h + penLength;
- penRect->bottom = thePt->v + penLength;
- }
-
-
- /******************************************************************************
- CalcDirtyRect
-
- Calculate the portion of the image drawn on by a pen. Find the
- rectangle which encloses the current dirtyRect and the current
- pen rectangle.
- ******************************************************************************/
-
- void CToolPens::CalcDirtyRect(
- LongRect *penRect)
- {
- dirtyRect.left = Min(dirtyRect.left, penRect->left);
- dirtyRect.top = Min(dirtyRect.top, penRect->top);
- dirtyRect.right = Max(dirtyRect.right, penRect->right);
- dirtyRect.bottom = Max(dirtyRect.bottom, penRect->bottom);
- }
-
-
- /******************************************************************************
- CalcDrawRgn
-
- Calculate the draw region affected by a pen. What a pain. We have
- to tweak the region depending on where the current point is in
- relation to the previous point because the pen hangs below and
- to the right of its location.
- ******************************************************************************/
-
- void CToolPens::CalcDrawRgn(
- LongRect *currRect,
- LongRect *prevRect,
- RgnHandle drawRgn)
- {
- OpenRgn();
-
- if (currRect->left > prevRect->left) {
- if (currRect->top > prevRect->top) {
- LMoveTo(currRect->right, currRect->top);
- LLineTo(currRect->right, currRect->bottom);
- LLineTo(currRect->left, currRect->bottom);
- LLineTo(prevRect->left, prevRect->bottom);
- LLineTo(prevRect->left, prevRect->top);
- LLineTo(prevRect->right, prevRect->top);
- LLineTo(currRect->right, currRect->top);
-
- } else {
- LMoveTo(currRect->left, currRect->top);
- LLineTo(currRect->right, currRect->top);
- LLineTo(currRect->right, currRect->bottom);
- LLineTo(prevRect->right, prevRect->bottom);
- LLineTo(prevRect->left, prevRect->bottom);
- LLineTo(prevRect->left, prevRect->top);
- LLineTo(currRect->left, currRect->top);
- }
-
- } else {
- if (currRect->top > prevRect->top) {
- LMoveTo(currRect->right, currRect->bottom);
- LLineTo(currRect->left, currRect->bottom);
- LLineTo(currRect->left, currRect->top);
- LLineTo(prevRect->left, prevRect->top);
- LLineTo(prevRect->right, prevRect->top);
- LLineTo(prevRect->right, prevRect->bottom);
- LLineTo(currRect->right, currRect->bottom);
-
- } else {
- LMoveTo(currRect->left, currRect->bottom);
- LLineTo(currRect->left, currRect->top);
- LLineTo(currRect->right, currRect->top);
- LLineTo(prevRect->right, prevRect->top);
- LLineTo(prevRect->right, prevRect->bottom);
- LLineTo(prevRect->left, prevRect->bottom);
- LLineTo(currRect->left, currRect->bottom);
- }
- }
-
- CloseRgn(drawRgn);
- }
-
-
- /******************************************************************************
- EndTracking {OVERRIDE}
-
- Mouse down tracking has ended because the user has released the
- mouse button. Its now time to set up the undo buffer and change
- the actual offscreen painting image.
- ******************************************************************************/
-
- void CToolPens::EndTracking(
- LongPt *currPt,
- LongPt *prevPt,
- LongPt *startPt)
- {
- /* Track for the last time */
- KeepTracking(currPt, prevPt, startPt);
-
- /* Create an undo bitmap */
- itsUndoBits = new CBitMap(dirtyRect.right - dirtyRect.left,
- dirtyRect.bottom - dirtyRect.top, FALSE);
-
- if (itsUndoBits->macBitMap == NULL) {
- TCLForgetObject(itsUndoBits); // couldn't allocate bitmap? KI 2/17/94
- } else {
- itsUndoBits->SetBoundsOrigin(dirtyRect.left, dirtyRect.top);
-
- /* Original image is on the scratchpad */
- /* Copy dirty area to undo bitmap */
- LCopyBits(gScratchPad->macBitMap, itsUndoBits->macBitMap,
- &dirtyRect, &dirtyRect, srcCopy, NULL);
- }
- }
-
-
- /******************************************************************************
- UseTool
- ******************************************************************************/
-
- void CToolPens::UseTool(
- LongPt *currPt,
- LongPt *prevPt)
- {
- } /* Null Method */
-
-
- /**** Methods for Different Pen Tools ****/
-
-
- /******************************************************************************
- CToolEraser {Eraser}
- ******************************************************************************/
-
- CToolEraser::CToolEraser(CPaintPane *aPaintPane,CBitMap *aPainting)
- : CToolPens(iERASER, aPaintPane, aPainting)
- {
- penLength = ERASER_LENGTH;
- }
-
-
- /******************************************************************************
- BeginTracking {Eraser}
- ******************************************************************************/
-
- void CToolEraser::BeginTracking(
- LongPt *startPt)
- {
- LongRect r;
-
- CToolPens::BeginTracking(startPt);
-
- CalcPenRect( startPt, &r);
- dirtyRect = r;
-
- LEraseRect(&r); /* Do erasure on screen */
-
- itsPainting->BeginDrawing(); /* Do erasure on offscreen bitmap */
- LEraseRect(&r);
- itsPainting->EndDrawing();
- }
-
-
- /******************************************************************************
- UseTool {Eraser}
- ******************************************************************************/
-
- void CToolEraser::UseTool(
- LongPt *currPt,
- LongPt *prevPt)
- {
- LongRect currRect;
- LongRect prevRect;
-
- CalcPenRect( currPt, &currRect);
- CalcPenRect( prevPt, &prevRect);
-
- CalcDirtyRect(&currRect); /* Determine changed area */
- CalcDrawRgn(&currRect, &prevRect, gUtilRgn);
-
- EraseRgn(gUtilRgn); /* Do erasure on screen */
-
- itsPainting->BeginDrawing(); /* Do erasure on offscreen bitmap */
- EraseRgn(gUtilRgn);
- itsPainting->EndDrawing();
- }
-
-
- /******************************************************************************
- IToolPencil {Pencil}
- ******************************************************************************/
-
- CToolPencil::CToolPencil(CPaintPane *aPaintPane,CBitMap *aPainting)
- : CToolPens(iPENCIL, aPaintPane, aPainting)
- {
- penLength = 1;
- }
-
-
- /******************************************************************************
- BeginTracking {Pencil}
- ******************************************************************************/
-
- void CToolPencil::BeginTracking(
- LongPt *startPt)
- {
- LongRect r;
- Pattern thePenPat;
-
- CToolPens::BeginTracking(startPt);
-
- CalcPenRect( startPt, &r);
- dirtyRect = r;
-
- PenNormal(); /* Start with a normal pen */
- if (itsPainting->PixelIsBlack( startPt)) {
- /* Pencil is on a black pixel */
- /* Subsequent drawing will create */
- /* white pixels */
- BlockMove(&qd.white, &thePenPat, 8);
-
- } else { /* Pencil is on a white pixel */
- /* Subsequent drawing will create */
- /* black pixels */
- BlockMove(&qd.black, &thePenPat, 8);
- }
-
- PenPat(&thePenPat); /* Do drawing on screen */
- LMoveTo(startPt->h, startPt->v);
- Line(0,0);
-
- itsPainting->BeginDrawing(); /* Do drawing on offscreen bitmap */
- PenPat(&thePenPat);
- LMoveTo(startPt->h, startPt->v);
- Line(0,0);
- itsPainting->EndDrawing();
- }
-
-
- /******************************************************************************
- UseTool {Pencil}
- ******************************************************************************/
-
- void CToolPencil::UseTool(
- LongPt *currPt,
- LongPt *prevPt)
- {
- LongRect currRect;
-
- CalcPenRect( currPt, &currRect); /* Determine changed area */
- CalcDirtyRect(&currRect);
-
- LMoveTo(prevPt->h, prevPt->v); /* Do drawing on screen */
- LLineTo(currPt->h, currPt->v);
-
- itsPainting->BeginDrawing(); /* Do drawing on offscreen bitmap */
- LMoveTo(prevPt->h, prevPt->v);
- LLineTo(currPt->h, currPt->v);
- itsPainting->EndDrawing();
- }
-
-
- /******************************************************************************
- CToolBrush {Paint Brush}
- ******************************************************************************/
-
- CToolBrush::CToolBrush(CPaintPane *aPaintPane,CBitMap *aPainting)
- : CToolPens(iPAINTING, aPaintPane, aPainting)
- {
- penLength = BRUSH_LENGTH;
- }
-
-
- /******************************************************************************
- BeginTracking {Paint Brush}
- ******************************************************************************/
-
- void CToolBrush::BeginTracking(
- LongPt *startPt)
- {
- LongRect r;
-
- CToolPens::BeginTracking(startPt);
-
- CalcPenRect( startPt, &r);
- dirtyRect = r;
-
- LFillRect(&r, &gPattern); /* Do painting on screen */
-
- itsPainting->BeginDrawing(); /* Do painting on offscreen bitmap */
- LFillRect(&r, &gPattern);
- itsPainting->EndDrawing();
- }
-
-
- /******************************************************************************
- UseTool {Paint Brush}
- ******************************************************************************/
-
- void CToolBrush::UseTool(
- LongPt *currPt,
- LongPt *prevPt)
- {
- LongRect currRect;
- LongRect prevRect;
-
- CalcPenRect( currPt, &currRect);
- CalcPenRect( prevPt, &prevRect);
-
- CalcDirtyRect(&currRect); /* Determine changed area */
- CalcDrawRgn(&currRect, &prevRect, gUtilRgn);
-
- FillRgn(gUtilRgn, &gPattern); /* Do painting on screen */
-
- itsPainting->BeginDrawing(); /* Do painting on offscreen bitmap */
- FillRgn(gUtilRgn, &gPattern);
- itsPainting->EndDrawing();
- }